<!DOCTYPE html>
<html lang="en">
    <head>
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>FPS Test</title>
        <style>
            html,
            body {
                margin: 0;
            }

            body * {
                box-sizing: border-box;
            }

            #main {
                width: 100vw;
                height: 100vh;
                overflow: hidden;
            }

            #fps {
                font-family: 'Sarasa Mono SC', monospace;
                position: fixed;
                top: 0.5rem;
                left: 0.5rem;
            }
        </style>
    </head>
    <body>
        <div id="main">
            <code id="fps"></code>
            <canvas id="anime"></canvas>
        </div>
    </body>
    <script>
        const main = document.getElementById('main');
        const fps = document.getElementById('fps');
        const canvas = document.getElementById('anime');
        let maxWidth = main.clientWidth;
        let maxHeight = main.offsetHeight;
        canvas.width = maxWidth;
        canvas.height = maxHeight;
        const ctx = canvas.getContext('2d');
        ctx.fillStyle = '#7f7f7f';
        let width = 30;
        let speed = 3;
        let angle = {
            value: (Math.PI / 2) * (Math.random() / 2 + 0.25),
            x: 0,
            y: 0,
            right: Math.random() > 0.5,
            bottom: Math.random() > 0.5,
            refresh: () => {
                angle.x = Math.sin(angle.value) * speed;
                angle.y = Math.cos(angle.value) * speed;
                angle.x = angle.right ? angle.x : -angle.x;
                angle.y = angle.bottom ? angle.y : -angle.y;
            }
        };
        angle.refresh();
        let position = {
            x: (maxWidth - width) * Math.random(),
            y: (maxHeight - width) * Math.random()
        };
        let count = 0;
        let frameCount = 0;
        let frameMax = undefined;
        let frameMin = undefined;
        let lastSecond = new Date().getSeconds();

        window.requestAnimationFrame(draw);

        function draw() {
            let nowSecond = new Date().getSeconds();
            frameCount++;
            if (lastSecond !== nowSecond) {
                fps.innerText = 'fps: ' + frameCount + '\nmax: ' + (frameMax ?? '') + '\nmin: ' + (frameMin ?? '');
                if (count > 1) {
                    frameMax = frameMax ? (frameCount > frameMax ? frameCount : frameMax) : frameCount;
                    frameMin = frameMin ? (frameCount < frameMin ? frameCount : frameMin) : frameCount;
                } else {
                    count++;
                }
                frameCount = 0;
                lastSecond = nowSecond;
            }
            ctx.clearRect(0, 0, maxWidth, maxHeight);
            let p = false;
            if (position.x + width > maxWidth) {
                angle.right = false;
                p = true;
            }
            if (position.x <= 0) {
                angle.right = true;
                p = true;
            }
            if (position.y + width > maxHeight) {
                angle.bottom = false;
                p = true;
            }
            if (position.y <= 0) {
                angle.bottom = true;
                p = true;
            }
            angle.refresh();
            if (p) {
                randomColor();
                randomAngle();
            }
            position.x += angle.x;
            position.y += angle.y;
            ctx.fillRect(position.x, position.y, width, width);
            window.requestAnimationFrame(draw);
        }

        function randomAngle() {
            angle.value = (Math.PI / 2) * (Math.random() / 2 + 0.25);
        }

        function randomColor() {
            ctx.fillStyle = `rgb(${100 + 127 * Math.random()}, ${100 + 127 * Math.random()}, ${100 + 127 * Math.random()})`;
        }

        document.body.addEventListener('dblclick', speedUp);
        {
            // Mobile
            let timer;
            let touchDuration = 500;
            document.body.addEventListener('touchstart', (e) => {
                timer = setInterval(speedUp, touchDuration);
            });
            document.body.addEventListener('touchend', (e) => {
                if (timer) clearTimeout(timer);
            });
        }
        {
            // PC
            let timerPc;
            let touchDuration = 500;
            document.body.addEventListener('mousedown', (e) => {
                timerPc = setInterval(speedUp, touchDuration);
            });
            document.body.addEventListener('mouseup', (e) => {
                if (timerPc) clearTimeout(timerPc);
            });
        }

        function speedUp() {
            speed *= 1.2;
        }
    </script>
</html>
